home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cubase Magazine 32
/
Issue #32.iso
/
3-TUTORIAL
/
TRIANTI
/
convoluzione
/
convolver.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-02-17
|
2KB
|
108 lines
#include <stdlib.h>
#include <string.h>
#include "convolver.h"
struct Convolver
{
float* x; /* buffer circolare (delay) contenente il segnale */
int N; /* dimensione del delay e dell'impulso */
float* h; /* risposta all'impulso */
int i; /* indice (del delay) da cui la lettura del segnale ha origine */
} typedef Convolver;
/*---------------------------------------------------------------
Crea una struttura per la convoluzione.
---------------------------------------------------------------*/
Convolver* Convolver_Crea (int N, float* h)
{
Convolver* c;
/* acquisisce memoria per un convolver */
c = malloc(sizeof(Convolver));
if (c == NULL) goto cleanup;
/* azzera la struttura */
memset(c, 0, sizeof(*c));
/* crea un buffer di delay e lo azzera */
c->x = malloc (sizeof(float)*N);
if (c->x == NULL) goto cleanup;
memset(c->x, 0, sizeof(float)*N);
/* acquisisce memoria per copiare la risposta all'impulso
e copia quella passata alla funzione nel buffer appena
creato */
c->h = malloc (sizeof(float)*N);
if (c->h == NULL) goto cleanup;
memcpy (c->h, h, sizeof(float)*N);
return c;
cleanup:
if (c)
{
if (c->x) free(c->x);
if (c->h) free(c->h);
free(c);
}
return 0;
}
/*---------------------------------------------------------------
Processa un campione
---------------------------------------------------------------*/
float Convolver_ProcessSample (Convolver* conv, float sample)
{
float acc = 0; /* accumulatore */
if (conv != 0)
{
int n, i;
i = conv->i; /* indice delay */
for (n = 0; n < conv->N; n++)
{
float delay, impulse;
delay = conv->x[i];
impulse = conv->h[n];
/* MAC */
acc += delay * impulse;
/* legge dal delay il prossimo campione */
if (++i >= conv->N) i = 0;
}
/* aggiorna il buffer di delay con il nuovo campione */
conv->x[conv->i] = sample;
/* aggiorna l'indice del delay */
if (++conv->i >= conv->N) conv->i = 0;
/* ritorna la somma tra prodotti tra l'impulso ed il segnale
contenuto nel delay */
}
return acc;
}
/*---------------------------------------------------------------
Distrugge la struttura per la convoluzione
---------------------------------------------------------------*/
void Convolver_Distruggi (Convolver* conv)
{
if (conv)
{
if (conv->x)
free(conv->x);
if (conv->h)
free(conv->h);
free(conv);
}
}